#ifndef DATASEGMENT_H_
#define DATASEGMENT_H_

#include "status.hxx"
#include "dbt.hxx"


// all of append and serial/deserial don't consider endiness yet
//the header of data segment file
class DataSegmentHeader
{
private:
    uint64_t m_version;
    uint64_t m_magic;

    static uint64_t MAGIC;

public:
    static uint32_t DATASEGMENT_HEADER_LENGTH;

public:
    DataSegmentHeader();

    std::string toString();

    bool checkHeader(){return m_magic == MAGIC; }

    std::string serialize();
    void deserialize(const std::string& data);
};
     
/**
 * manage the access of a data segment 
 */ 
class DataSegment
{
public:
    enum SegMode {
        READ_ONLY,
        READ_WRITE,
    };


protected:
    uint32_t m_segid;
    uint32_t m_capacity;
    std::string m_partitionPath;
    
    uint32_t m_dataSize;
    uint32_t m_alive;

    SegMode m_segMode;

public:
    DataSegment(uint32_t segId, const std::string& partitionPath, uint32_t capacity);
    virtual ~DataSegment() {}

    virtual DbStatus init() = 0;

    uint32_t getSegId() {return m_segid;}
    std::string getPath() {return m_partitionPath; }
    uint32_t getCapacity() {return m_capacity; }
    void setMode(SegMode mode) {m_segMode = mode;}
    bool isReadOnly(){return m_segMode == READ_ONLY;}

    //get the valid data size of the segment
    virtual uint32_t getActualDataSize() = 0;

    //including length and data size
    virtual uint32_t changeDataSize(int32_t size) = 0;
    virtual bool isAlive() = 0;
    virtual void setAlive(bool live) = 0;
    virtual void closeWriter() = 0;

    //appending
    virtual DbStatus appendShort(uint16_t value) = 0;
    virtual DbStatus appendInt(uint32_t value) = 0;
    virtual DbStatus appendLong(uint64_t value) = 0;
    virtual DbStatus append(const std::string& data, uint32_t& offset) = 0;
    virtual DbStatus append(Dbt& dbt, uint32_t& offset) = 0;

    //reading
    virtual DbStatus readShort(uint32_t offset, uint16_t& value) = 0;
    virtual DbStatus readInt(uint32_t offset, uint32_t& value) = 0;
    virtual DbStatus readLong(uint32_t offset, uint64_t& value) = 0;
    virtual DbStatus read(uint32_t offset, uint32_t& size, std::string& result) = 0;
    virtual DbStatus read(uint32_t offset, uint32_t& size, Dbt& dbt) = 0;

    virtual DbStatus flush() = 0;
    virtual DbStatus dropCache() = 0;

    //for reocvery only
    virtual DbStatus write(uint32_t offset, const std::string& data) = 0;

    //including length and data size
    virtual void setDataSize(int32_t size) = 0;

    //notiry compact to start
    virtual void notifyCompact() = 0;
};

#endif
